package com.ruoyi.web.controller.task;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.WaterMeter;
import com.ruoyi.system.domain.WaterYcmeterDatahistory;
import com.ruoyi.system.service.IWaterInterfaceService;
import com.ruoyi.system.service.IWaterMeterDatahistoryService;
import com.ruoyi.system.service.IWaterMeterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @description 定时获取水表数据 采集频率5分钟，6小时上报
 * @data 2025/9/26 17:12
 */
@Component
public class TaxWaterDataTask {

    @Autowired
    private IWaterMeterDatahistoryService datahistoryService;
    @Autowired
    private IWaterInterfaceService waterInterfaceService;
    @Autowired
    private IWaterMeterService waterMeterService;
    @Autowired
    private RedisCache redisCache;

    /**
     * 定时获取拓安信水表数据 采集频率5分钟，6小时上报  00:00 6:00 12:00 18:00
     * 每6小时 1小时后执行，查询95分钟前的数据并存储
     */
    @Scheduled(cron = "0 31 1,7,13,19 * * ?")
    public void collectTAXData() {
        String meterNo = "2412208000";
        WaterMeter waterMeter = waterMeterService.selectWaterMeterByMeterNo(meterNo);
        List<DeviceTime> deviceTimes =redisCache.getCacheList(meterNo);
        triggerCompensation(deviceTimes,waterMeter);
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -95);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String startTime = sdf.format(calendar.getTime());
        int num = datahistoryService.syncWaterMeterData(waterMeter,startTime);
        if(num==0){
            saveDeviceTime(meterNo,startTime);
        }
    }


    /**
     * 定时获取拓安信水表数据 采集频率5分钟，8小时上报  00:00 8:00 16:00
     * 每6小时 1点半小时后执行，查询18点和0点的数据并存储
     */
    @Scheduled(cron = "0 31 1 * * ?")
    public void collectTAX1Data1() {
        List<WaterMeter> waterMeters =getWaterMeterList();
        String previousDay = DateUtils.getPreviousDay(DateUtils.getDate());
        String startTime1 = previousDay + " 17:58";
        String startTime = previousDay + " 23:58";
        for (WaterMeter meter : waterMeters) {
            if("TAX".equals(meter.getCreateBy())){ // 拓安信水表
                try {
                    int a = datahistoryService.syncWaterMeterData(meter,startTime1);  //查询 昨天 18:00 的数据
                    if(a==0){
                        saveDeviceTime(meter.getMeterNo(),startTime1);
                    }
                    Thread.sleep(3000);
                    int b = datahistoryService.syncWaterMeterData(meter,startTime);
                    if(b==0){
                        saveDeviceTime(meter.getMeterNo(),startTime);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @Scheduled(cron = "0 31 9 * * ?")
    public void collectTAX1Data2() {
        List<WaterMeter> waterMeters =getWaterMeterList();
        String startTime = DateUtils.getDate() + " 05:58";
        for (WaterMeter meter : waterMeters) {
            if("TAX".equals(meter.getCreateBy())){ // 拓安信水表
                int num = datahistoryService.syncWaterMeterData(meter,startTime);
                if(num==0){
                    saveDeviceTime(meter.getMeterNo(),startTime);
                }
            }
        }
    }
    @Scheduled(cron = "0 31 17 * * ?")
    public void collectTAX1Data3() {
        List<WaterMeter> waterMeters =getWaterMeterList();
        String startTime = DateUtils.getDate() + " 11:58";
        for (WaterMeter meter : waterMeters) {
            if("TAX".equals(meter.getCreateBy())){ // 拓安信水表
                int num = datahistoryService.syncWaterMeterData(meter,startTime);
                if(num==0){
                    saveDeviceTime(meter.getMeterNo(),startTime);
                }
            }
        }
    }

    /**
     * 定时获取新天科技水表数据 采集频率5分钟，6小时上报  00:30 6:30 12:30 18:30
     * 每6小时 1小时后执行，查询1小时前的数据并存储
     */
    @Scheduled(cron = "0 38 1,7,13,19 * * ?")
    public void collectXTKJData() {
        List<WaterMeter> waterMeters =getWaterMeterList();
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -99);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String startTime = sdf.format(calendar.getTime());
        String endTime = DateUtils.getTime();
        for (WaterMeter meter : waterMeters) {
            if("XTKJ".equals(meter.getCreateBy())){  // 新天科技水表
                int num = waterInterfaceService.syncXTKJWaterMeterData(meter,startTime,endTime);
                if(num==0){
                    saveDeviceTime(meter.getMeterNo(),startTime);
                }
            }
        }
    }

    // 定义四个时间点
    private static final List<LocalTime> TIME_POINTS = Arrays.asList(
            LocalTime.of(0, 0),   // 0点
            LocalTime.of(6, 0),   // 6点
            LocalTime.of(12, 0),  // 12点
            LocalTime.of(18, 0)   // 18点
    );
    /**
     * 定时获取创源水表数据 采集频率5分钟，6小时上报  00:05 6:05 12:05 18:05
     * 每6小时 执行一次，查询5分钟前的数据并存储
     */
    @Scheduled(cron = "0 5 0,6,12,18 * * ?")
    public void collectCYData() {
        List<WaterMeter> waterMeters =getWaterMeterList();
        List<WaterYcmeterDatahistory> waterDataList = waterInterfaceService.selectCYWaterMeterData();
        if (StringUtils.isNotEmpty(waterDataList)){
            Map<String,WaterYcmeterDatahistory> waterDataMap = waterDataList.stream().collect(Collectors.toMap(
                    WaterYcmeterDatahistory::getMeterNo,
                    item -> item,
                    // 使用字符串比较，取最大的字符串（即最近的日期）
                    (existing, replacement) -> existing.getReadDate().compareTo(replacement.getReadDate()) > 0 ? existing : replacement
            ));
            LocalTime timePoint = DateUtils.findNearestTimePointSimplified(TIME_POINTS, LocalTime.now());
            for (WaterMeter meter : waterMeters) {
                if("CY".equals(meter.getMaker())){  // 创源水表
                    WaterYcmeterDatahistory realData = waterDataMap.get(meter.getMeterNo());
                    if(realData==null){
                        continue;
                    }
                    String readDate = realData.getReadDate()+":00";
                    if(isMoreThanHour(readDate)){  // 如果数据已经超过7小时，则不处理
                        continue;
                    }
                    realData.setReadDate(DateUtils.getDate()+" " + timePoint);
                    waterInterfaceService.syncCYWaterMeterRealData(meter,realData);
                }
            }
        }
    }

    private boolean isMoreThanHour(String readDate){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String currentTime = DateUtils.getTime();
        LocalDateTime dateTime1 = LocalDateTime.parse(readDate, formatter);
        LocalDateTime dateTime2 = LocalDateTime.parse(currentTime, formatter);
        // 计算时间差的绝对值
        Duration duration = Duration.between(dateTime1, dateTime2).abs();
        return duration.toHours() >= 7;
    }

    /**
     * 定时补偿机制
     */
    @Scheduled(cron = "0 0 0/2 * * ?")
    public void compensationCheck() {
        List<WaterMeter> waterMeters =getWaterMeterList();
        for (WaterMeter meter : waterMeters) {
            List<DeviceTime> deviceTimes =redisCache.getCacheList(meter.getMeterNo());
            if(StringUtils.isEmpty(deviceTimes)){
                continue;
            }
            if("TAX".equals(meter.getCreateBy())||"XTKJ".equals(meter.getCreateBy())){
                triggerCompensation(deviceTimes,meter);
            }
        }
    }

    /**
     * 补偿机制
     * @param deviceTimes
     * @param waterMeter
     */
    private void triggerCompensation(List<DeviceTime> deviceTimes, WaterMeter waterMeter){
        String meterNo = waterMeter.getMeterNo();
        if(deviceTimes!=null && deviceTimes.size()>0){  //补偿机制（取失败的时间点重新获取数据）
            List<DeviceTime> deviceTimess = new ArrayList<>();
            for(DeviceTime device : deviceTimes){
                int num = 1;
                if("TAX".equals(waterMeter.getCreateBy())||"2412208000".equals(meterNo)){
                    num = datahistoryService.syncWaterMeterData(waterMeter,device.getTimePoint());
                }
                if("XTKJ".equals(waterMeter.getCreateBy())){
                    String startTime = device.getTimePoint();
                    LocalDateTime date = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                    String endTime = date.plusHours(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
                    num = waterInterfaceService.syncXTKJWaterMeterData(waterMeter,startTime,endTime);
                }
                if(num==0){
                    DeviceTime deviceTime = new DeviceTime();
                    deviceTime.setDeviceId(waterMeter.getMeterNo());
                    deviceTime.setTimePoint(device.getTimePoint());
                    deviceTimess.add(deviceTime);
                }
            }
            redisCache.setCacheList(meterNo,deviceTimess); //保存设备时间点
        }
    }

    /**
     * 保存设备时间点
     * @param meterNo
     * @param timePoint
     */
    private void saveDeviceTime(String meterNo, String timePoint) {
        List<DeviceTime> deviceTimes =redisCache.getCacheList(meterNo);
        if (deviceTimes == null) {
            deviceTimes = new ArrayList<>();
        }
        DeviceTime deviceTime = new DeviceTime();
        deviceTime.setDeviceId(meterNo);
        deviceTime.setTimePoint(timePoint);
        deviceTimes.add(deviceTime);
        redisCache.setCacheList(meterNo, deviceTimes);
    }


    private List<WaterMeter> getWaterMeterList() {
        WaterMeter waterMeter = new WaterMeter();
        waterMeter.setMeterType("0"); // 0:远传表
        List<WaterMeter> waterMeters =waterMeterService.selectWaterMeterList(waterMeter);
        return waterMeters;
    }
}
